home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / 031-040 / amok32 / tasksupport / tasksupport.mod < prev    next >
Text File  |  1993-11-04  |  7KB  |  240 lines

  1. (**********************************************************************
  2.  
  3.     :Program.    TaskSupport.mod
  4.     :Contents.   multitasking, creates true Dos-processes
  5.     :Support.    Bernd Preusing's module "MultiTasking" helped me a lot!
  6.     :Author.     Nicolas Benezan [bne]
  7.     :Address.    Postwiesenstr. 2, D7000 Stuttgart 60
  8.     :Phone.      711/333679
  9.     :Copyright.  Public Domain
  10.     :Language.   Modula-2, INLINE code
  11.     :Translator. M2Amiga A+L V3.27d! Check LaunchTask() if other V. !!!
  12.     :History.    V1.0 [bne] 09.Jan.1990 (exec tasks only)
  13.     :History.    V1.1 [bne] 10.Jan.1990 (+ dos processes)
  14.  
  15. **********************************************************************)
  16.  
  17. IMPLEMENTATION MODULE TaskSupport;
  18.  
  19. FROM Arts        IMPORT stackTop, TermProcedure;
  20. FROM Dos         IMPORT FileHandlePtr, Process, ProcessId, ProcessPtr;
  21. FROM Exec        IMPORT AddHead, AddTask, AllocEntry, Byte, execBase,
  22.                         FindTask, Forbid, MemEntry, MemList, MemReqs,
  23.                         MemReqSet, MinList, MinNode, MsgPortAction,
  24.                         NodeType, Permit, Remove, RemTask, sigChild,
  25.                         sigDos, Signal, Task, TaskFlags, TaskFlagSet,
  26.                         TaskPtr, Wait;
  27. FROM ExecSupport IMPORT CreatePort, DeletePort, NewList;
  28. FROM SYSTEM      IMPORT ADDRESS, ADR, BPTR, CAST, INLINE, LONGSET, REG,
  29.                         SETREG;
  30.  
  31. TYPE
  32.   TaskMemList = RECORD
  33.     memList: MemList;
  34.     taskEntry: MemEntry;
  35.     stackEntry: MemEntry;
  36.     argEntry: MemEntry;
  37.   END;
  38.   TaskMemListPtr = POINTER TO TaskMemList;
  39.   TaskExtension = RECORD
  40.     node: MinNode;
  41.     stack: ADDRESS;
  42.     proc: TaskProc;
  43.     arg: ADDRESS;
  44.     me: TaskPtr;
  45.     father: TaskPtr;
  46.   END;
  47.   TaskExtensionPtr = POINTER TO TaskExtension;
  48.   MinExtension = RECORD
  49.     node: MinNode;
  50.     stack: ADDRESS;
  51.   END;
  52.  
  53. VAR
  54.   TaskList: MinList;
  55.   MainExtension: MinExtension;
  56.   MainProcess: ProcessPtr;
  57.   GlobVec, WindowPtr: ADDRESS;
  58.   StdIn, StdOut: FileHandlePtr;
  59.   ConsoleTask, FileSystemTask: ProcessId;
  60.  
  61. (* $R- $S- $V- *)
  62. CONST
  63.   RTS = 04E75H;
  64.  
  65. PROCEDURE LaunchTask (ThisTask{11}: TaskPtr;
  66.                       Unused{10}: ADDRESS;
  67.                       FakeReg{8}: TaskExtensionPtr); (* $E- *)
  68.   BEGIN
  69.     FakeReg:= ThisTask^.userData;
  70.     stackTop:= FakeReg^.stack;
  71.     INLINE (RTS);
  72.   END LaunchTask;
  73.  
  74. PROCEDURE SwitchTask (ThisTask{11}: TaskPtr;
  75.                       Unused{10}: ADDRESS;
  76.                       FakeReg{8}: TaskExtensionPtr); (* $E- *)
  77.   BEGIN
  78.     FakeReg:= ThisTask^.userData;
  79.     FakeReg^.stack:= stackTop;
  80.     INLINE (RTS);
  81.   END SwitchTask;
  82. (* $R= $S= $V= *)
  83.  
  84. PROCEDURE RemoveTask (ExtensionPtr: TaskExtensionPtr);
  85.   BEGIN
  86.     Forbid;
  87.     Remove (ExtensionPtr);
  88.     RemTask (ExtensionPtr^.me);
  89.     Permit;
  90.   END RemoveTask;
  91.  
  92. PROCEDURE StartTask;
  93.   VAR
  94.     ExtensionPtr: TaskExtensionPtr;
  95.     ThisProcess: ProcessPtr;
  96.   BEGIN
  97.     ThisProcess:= CAST (ProcessPtr, FindTask (NIL));
  98.     ExtensionPtr:= ThisProcess^.task.userData;
  99.     WITH ExtensionPtr^ DO
  100.       ThisProcess^.returnAddr:= REG (15);
  101.       Signal (father, LONGSET{sigChild});
  102.       proc (arg);
  103.     END;
  104.     RemoveTask (ExtensionPtr);
  105.   END StartTask;
  106.  
  107. PROCEDURE CreateTask (Proc: TaskProc;
  108.                       InitArg: ADDRESS;
  109.                       Name: ADDRESS;
  110.                       StackSize: LONGINT;
  111.                       Priority: Byte): TaskPtr;
  112.   CONST
  113.     NodeTypeMsgPort = msgPort;
  114.   VAR
  115.     NewProcess: ProcessPtr; (* forget Dos.CreateProc ! *)
  116.     TaskMem: TaskMemList;
  117.     TaskMemPtr: TaskMemListPtr;
  118.     ExtensionPtr: TaskExtensionPtr;
  119.   BEGIN
  120.     WITH TaskMem DO
  121.       memList.numEntries:= 3;
  122.       taskEntry.reqs  := MemReqSet{public, memClear};
  123.       taskEntry.length:= SIZE (Process);
  124.       stackEntry.reqs  := MemReqSet{memClear};
  125.       stackEntry.length:= StackSize;
  126.       argEntry.reqs  := MemReqSet{memClear};
  127.       argEntry.length:= SIZE (TaskExtension);
  128.     END;
  129.     TaskMemPtr:= CAST (TaskMemListPtr, AllocEntry (ADR (TaskMem)));
  130.     IF LONGINT (TaskMemPtr) > 0 THEN
  131.       WITH TaskMemPtr^ DO
  132.         NewProcess:= taskEntry.addr;
  133.         ExtensionPtr:= argEntry.addr;
  134.         WITH NewProcess^ DO
  135.           WITH task DO
  136.             spLower  := stackEntry.addr;
  137.             spUpper  := spLower;
  138.             INC (spUpper, StackSize);
  139.             spReg    := spUpper;
  140.             node.type:= process;
  141.             node.pri := Priority;
  142.             node.name:= Name;
  143.             NewList (ADR (memEntry));
  144.             AddHead (ADR (memEntry), TaskMemPtr);
  145.             launch   := CAST (PROC, ADR (LaunchTask));
  146.             switch   := CAST (PROC, ADR (SwitchTask));
  147.             userData := ExtensionPtr;
  148.           END;
  149.           WITH msgPort DO
  150.             node.type:= NodeTypeMsgPort;
  151.             flags:= signal;
  152.             sigBit:= sigDos;
  153.             sigTask:= ADR (task);
  154.             NewList (ADR (msgList));
  155.           END;
  156.           stackSize     := StackSize;
  157.           globVec       := GlobVec;
  158.           stackBase     := BPTR (task.spUpper);
  159.           cis           := StdIn;
  160.           cos           := StdOut;
  161.           consoleTask   := ConsoleTask;
  162.           fileSystemTask:= FileSystemTask;
  163.           windowPtr     := WindowPtr;
  164.           WITH ExtensionPtr^ DO
  165.             stack:= LONGINT (task.spLower) + 512;
  166.             proc:= Proc;
  167.             arg:= InitArg;
  168.             me:= ADR (task);
  169.             father:= FindTask (NIL);
  170.           END;
  171.         END;
  172.         Forbid;
  173.         AddHead (ADR (TaskList), ExtensionPtr);
  174.         AddTask (ADR (NewProcess^.task), ADR (StartTask), NIL);
  175.         NewProcess^.task.flags:= TaskFlagSet{launch, switch};
  176.         Permit;
  177.         SETREG (0, Wait (LONGSET{sigChild}));
  178.       END;
  179.       RETURN ADR (NewProcess^.task)
  180.     END;
  181.     RETURN NIL
  182.   END CreateTask;
  183.  
  184. PROCEDURE DeleteTask (Task: TaskPtr);
  185.   VAR
  186.     Node: TaskExtensionPtr;
  187.   BEGIN
  188.     Forbid;
  189.     Node:= CAST (TaskExtensionPtr, TaskList.head);
  190.     WHILE Node^.node.succ # NIL DO
  191.       IF Node^.me = Task THEN
  192.         RemoveTask (Node);
  193.         Permit;
  194.         RETURN
  195.       END;
  196.       Node:= CAST (TaskExtensionPtr, Node^.node.succ);
  197.     END;
  198.     Permit;
  199.   END DeleteTask;
  200.  
  201. PROCEDURE Cleanup;
  202.   BEGIN
  203.     WHILE TaskList.head^.succ # NIL DO
  204.       RemoveTask (CAST (TaskExtensionPtr, TaskList.head));
  205.     END;
  206.   END Cleanup;
  207.  
  208. PROCEDURE InstallLaunchSwitch;
  209.   CONST
  210.     LaunchSwitchFlags = TaskFlagSet{launch, switch};
  211.   BEGIN
  212.     Forbid;
  213.     MainExtension.stack:= stackTop;
  214.     WITH MainProcess^.task DO
  215.       userData:= ADR (MainExtension);
  216.       launch:= CAST (PROC, ADR (LaunchTask));
  217.       switch:= CAST (PROC, ADR (SwitchTask));
  218.       flags:= flags + LaunchSwitchFlags;
  219.     END;
  220.     Permit;
  221.   END InstallLaunchSwitch;
  222.  
  223. BEGIN
  224.   MainProcess:= CAST (ProcessPtr, FindTask (NIL));
  225.   WITH MainProcess^ DO
  226.     GlobVec       := globVec;
  227.     StdIn         := cis;
  228.     StdOut        := cos;
  229.     ConsoleTask   := consoleTask;
  230.     FileSystemTask:= fileSystemTask;
  231.     WindowPtr     := windowPtr;
  232.   END;
  233.   NewList (ADR (TaskList));
  234.   TermProcedure (Cleanup);
  235.   InstallLaunchSwitch;
  236. END TaskSupport.
  237.  
  238.  
  239.  
  240.